package org.snail.attendence.mapper;

import lombok.NonNull;
import lombok.extern.log4j.Log4j;
import org.snail.attendence.bean.*;
import org.snail.base.AttendenceCondition;
import org.snail.common.DateUtils;
import org.snail.common.StringUtils2;
import org.snail.constant.ErrCodeConstant;
import org.snail.constant.MongoCollectionConstant;
import org.snail.constant.WorkSheetConstant;
import org.snail.exception.CommonException;
import org.snail.exception.EmpException;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Repository
@Log4j
public class AttendenceMongoMapper {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 从mongo中取出异常考勤
     */
    public List findAbAttendenceMgDBList(AttendenceCondition aliCondition) throws CommonException {
        Query attendenceQuery = new Query();
        if (null == aliCondition){
           mongoTemplate.findAll(AbnormalAttendanceDTO.class);
        }
        if (null != aliCondition.getGroupId()){
            attendenceQuery.addCriteria(Criteria.where("groupDO.id").is(aliCondition.getGroupId()));   //根据群组来查询
        }
        if (!StringUtils.isEmpty(aliCondition.getEmployeeName())){
            attendenceQuery.addCriteria(Criteria.where("employeesDO.name").regex(aliCondition.getEmployeeName()));
        }
        attendenceQuery.addCriteria(Criteria.where("abnormalAttendanceDTOList.isCorrect").is(aliCondition.getIsCorrect()));
        attendenceQuery.addCriteria(Criteria.where("abnormalAttendanceDTOList.aliNumber").is(aliCondition.getIsCorrect()));
        // "startDate":{$lte:new Date(2012,11,7)},"endDate":{$gte:new Date(2012,11,7)}。
        List<AbAttendenceMongo> abAttendenceMongos = new ArrayList<>();
//        Date latestTime = findAbAttListByLatest();
//        if(null != latestTime){
//            attendenceQuery.addCriteria(new Criteria("insertTime").is(latestTime));
//        }
        try{
            abAttendenceMongos = mongoTemplate.find(attendenceQuery, AbAttendenceMongo.class);
        }catch (Exception e){
            log.error("mongoDB多条件查询操作失败！", e);
            throw new CommonException(ErrCodeConstant.DB_ERR, "mongoDB多条件查询操作失败！", e);
        }
        return abAttendenceMongos;
    }

    /**
     * 新增异常记录（map格式）
     *
     *
     */
    public int saveGeneralAttendence(Object mongoObject,String mongoDBName) throws CommonException {
        int result = 0;
        try {
            mongoTemplate.insert(mongoObject,mongoDBName);
            result = 1;
        } catch(Exception e) {
            log.error("mongoDB新增操作异常！保存对象：" + mongoObject + e);
            throw new CommonException(ErrCodeConstant.DB_ERR, "mongoDB新增操作异常！", e);
        }
        return result;
    }

    /**
     * 保存异常记录list至mongoDB中(异常考勤正常考勤通用)
     *
     */
    public int saveAttendenceList(List mongoObject, String mongoDBName) throws CommonException {
        int result = 0;
        if (StringUtils.isEmpty(mongoDBName)) {
            log.error("存入临时考勤时，没有mongoDB名称！");
        }
        try {
            mongoTemplate.insert(mongoObject, mongoDBName);
            result = 1;
        } catch(Exception e) {
            log.error("mongoDB新增操作异常！" + e);
            throw new CommonException(ErrCodeConstant.DB_ERR, "mongoDB新增操作异常！", e);
        }
        return result;
    }

    /**
     * 强行将某条数据改为正常,修改一条记录
     *
     * @param abnormalAttendanceDTO 标记异常的对象
     *
     */
    public void editNormal(AbnormalAttendanceDTO abnormalAttendanceDTO) throws CommonException {
        if (null == abnormalAttendanceDTO){
            log.error("异常考勤标记操作失败！该异常考勤对象为空");
        }
        Query query = new Query();
        Update update = Update.update("isCorrect", abnormalAttendanceDTO.getIsCorrect());   //根据角标取值

        query.addCriteria(Criteria.where("dateStr").is(abnormalAttendanceDTO.getDateStr()));
        if (!StringUtils2.objIsNull(abnormalAttendanceDTO.getAliNumber())){  //根据外包工号查找
            query.addCriteria(Criteria.where("aliNumber").is(abnormalAttendanceDTO.getAliNumber()));
        }else{      //根据其他查找唯一值
            query.addCriteria(Criteria.where("employeeName").is(abnormalAttendanceDTO.getEmployeeName()));
            query.addCriteria(Criteria.where("department").is(abnormalAttendanceDTO.getDepartment()));
        }
        try{
            mongoTemplate.updateMulti(query, update, AbnormalAttendanceDTO.class);
        }catch (Exception e){
            log.error("异常考勤标记操作失败！该异常考勤对象为" + abnormalAttendanceDTO, e);
            throw new CommonException(ErrCodeConstant.DB_ERR, "异常考勤标记操作失败！该异常考勤对象为" + abnormalAttendanceDTO, e);
        }
    }

    /**
     * 将考勤列表保存至mongoDB中
     *
     * @param aliWorkDTO 传对象
     */
    public void saveAttendence(AliWorkDTO aliWorkDTO) throws CommonException {
        try{
            mongoTemplate.insert(aliWorkDTO);
        }catch (Exception e){
            log.error("考勤列表存入mgDB操作异常！", e);
            throw new CommonException(ErrCodeConstant.DB_ERR, "考勤列表存入mgDB操作异常！", e);
        }
    }

    /**
     * 多条件查询异常考勤记录
     * @param aliCondition
     * @return
     * @throws EmpException
     */
    public List<AbnormalAttendanceDTO> findAbnornalList(AttendenceCondition aliCondition) throws EmpException {
        List<AbnormalAttendanceDTO> abnormalListByMix = null;
        Query query = new Query();
        if (!StringUtils.isEmpty(aliCondition.getFastInquiry())) {
            return getFastInquiryList(aliCondition.getFastInquiry());   //快速查询和精确查询区分开来
        }
        if (aliCondition == null) {
            return mongoTemplate.findAll(AbnormalAttendanceDTO.class);
        }
        if (WorkSheetConstant.FLAG_CORRECT == aliCondition.getIsCorrect() || WorkSheetConstant.FLAG_NORMAL == aliCondition.getIsCorrect()){
            query.addCriteria(Criteria.where("isCorrect").is(aliCondition.getIsCorrect()));
        }
        if (null != aliCondition.getGroupIds() && aliCondition.getGroupIds().size() > 1) {
            query.addCriteria(new Criteria("groupId").in(aliCondition.getGroupIds()));
        }
        if (!StringUtils.isEmpty(aliCondition.getEmployeeName())) {
            query.addCriteria(Criteria.where("employeeName").regex(aliCondition.getEmployeeName()));
        }
        abnormalListByMix = mongoTemplate.find(query, AbnormalAttendanceDTO.class);
        return abnormalListByMix;
    }



//    /**
//     * 重新将标记正常的数据插入新的数据库
//     * @param abnormalAttendanceDTOs  List<AbnormalAttendanceDTO>异常考勤列表
//     */
//    public void reEditNormal(List<AbnormalAttendanceDTO> abnormalAttendanceDTOs) throws CommonException {
//        for (AbnormalAttendanceDTO abnormalAttendanceDTO : abnormalAttendanceDTOs){
//            editNormal(abnormalAttendanceDTO);
//        }
//    }
    /**
     * 查找出标记正常的值
     *
     * @param isCorrect   这个是强行标记的字段
     * @return correctAttendences 查找出被标记为正常的数值
     */
    public List<AbnormalAttendanceDTO> findListByFlag(Integer isCorrect){
        Query query = Query.query(Criteria.where("isCorrect").is(isCorrect));
        return mongoTemplate.find(query, AbnormalAttendanceDTO.class);
    }

    /**
     * 新增表 totalAttendence
     * @param attendenceMongo 里面有file文件，存放考勤Excel文件
     */
    public void insertAttendenceMongo(AttendenceMongo attendenceMongo) {
        mongoTemplate.insert(attendenceMongo, "totalAttendence");
    }


    /**
     * 查找出有请假的list,便于核对微信考勤值
     *
     * @param aliWorkDTO AliWorkDTO对象
     * @return  approvals 根据相关查询条件返回List<AttendenceMongo>
     */
    public List<AttendenceMongo> findListContainsApproval(AliWorkDTO aliWorkDTO) {
        Query query = Query.query(Criteria.where("approval").ne(""));    //不等于空
        List<AttendenceMongo> approvals = mongoTemplate.find(query, AttendenceMongo.class);
        return approvals;
    }


    /**
     * 如果没有值则上传，有值则更新,方便Excel更新
     *
     * @param aliWorkDTOS 传入的是List<AliWork>
     */
    public void addOrUpDateAttendence(List<AliWorkDTO> aliWorkDTOS) {
        for (AliWorkDTO aliWorkDTO : aliWorkDTOS) {
            Query query = new Query(new Criteria("employeeName").is(aliWorkDTO.getEmployeeName()).and("dateStr").is(aliWorkDTO.getDateStr()));
            List<AliWorkDTO> aliAttendence = mongoTemplate.find(query, AliWorkDTO.class);
            if (aliAttendence.isEmpty()) {
                mongoTemplate.insert(aliWorkDTO);
            } else {
                Update update = Update.update("punchComment1", aliWorkDTO.getPunchComment1()).set("punchComment2", aliWorkDTO.getPunchComment2())
                        .set("approval", aliWorkDTO.getApproval()).set("attendenceMin", aliWorkDTO.getAttendenceMin());
                mongoTemplate.updateFirst(query, update, aliWorkDTO.getClass());
            }

        }

    }

    /**
     * 根据月份查询，并且不显示被标记的数据,或者是群组来查找
     *
     * @param  condition 将一些常用查询参数都封装到了一个condition类中
     * @return
     */
    public List<AliWorkDTO> findListByCondition(AttendenceCondition condition) throws EmpException {
        Query query = new Query();
        if (!StringUtils2.objIsNull(condition)){
            if (!StringUtils2.isNull(condition.getDateStr())){

                query.addCriteria(Criteria.where("dateStr").is(condition.getDateStr()));
            }
            if (!StringUtils2.isNull(condition.getAliNumber())){
                query.addCriteria(Criteria.where("aliNumber").is(condition.getAliNumber()));
            }
            if (!StringUtils2.isNull(condition.getEmployeeName())){
                query.addCriteria(Criteria.where("employeeName").is(condition.getEmployeeName()));
            }
            if (!StringUtils2.isNull(condition.getPunchComment1())){
                query.addCriteria(Criteria.where("punchComment1").is(condition.getPunchComment1()));
            }
            if (!StringUtils2.isNull(condition.getPunchComment2())){
                query.addCriteria(Criteria.where("punchComment2").is(condition.getPunchComment2()));
            }
            if (!StringUtils2.isNull(condition.getPunchComment3())){
                query.addCriteria(Criteria.where("punchComment3").is(condition.getPunchComment3()));
            }
            if (!StringUtils2.isNull(condition.getApproval())){
                query.addCriteria(Criteria.where("approval").is(condition.getApproval()));
            }
            if (condition.getGroupNames()!=null && !condition.getGroupNames().isEmpty()){
                //字段遍历查询   可能不能模糊查询
                query.addCriteria(Criteria.where("groupName").in(condition.getGroupNames()));
            }
            query.addCriteria(Criteria.where("isCorrect").is(condition.getIsCorrect()));
        }else {
            throw new EmpException(ErrCodeConstant.ILLEGAL_PARAM, "考勤字段不能为空！", condition);
        }
        List<AliWorkDTO> attendencesByCondition = mongoTemplate.find(query, AliWorkDTO.class);
        return attendencesByCondition;
    }

    /**
     * 根据月份查询，并且不显示被标记的数据,或者是群组来查找
     *
     * @param  condition 将一些常用查询参数都封装到了一个condition类中
     * @return
     */
    public List<AliWorkDTO> findListByCondition(AttendenceCondition condition, String collectionName) throws EmpException {
        if (StringUtils.isEmpty(collectionName)){
            log.error("考勤数据为空！");
        }
        Query query = new Query();
        if (!StringUtils2.objIsNull(condition)){
            if (!StringUtils2.isNull(condition.getDateStr())){
                query.addCriteria(Criteria.where("dateStr").is(condition.getDateStr()));
            }
            if (!StringUtils2.isNull(condition.getAliNumber())){
                query.addCriteria(Criteria.where("aliNumber").is(condition.getAliNumber()));
            }
            if (!StringUtils2.isNull(condition.getEmployeeName())){
                query.addCriteria(Criteria.where("employeeName").is(condition.getEmployeeName()));
            }
            if (!StringUtils2.isNull(condition.getPunchComment1())){
                query.addCriteria(Criteria.where("punchComment1").is(condition.getPunchComment1()));
            }
            if (!StringUtils2.isNull(condition.getPunchComment2())){
                query.addCriteria(Criteria.where("punchComment2").is(condition.getPunchComment2()));
            }
            if (!StringUtils2.isNull(condition.getPunchComment3())){
                query.addCriteria(Criteria.where("punchComment3").is(condition.getPunchComment3()));
            }
            if (!StringUtils2.isNull(condition.getApproval())){
                query.addCriteria(Criteria.where("approval").is(condition.getApproval()));
            }
            if (condition.getGroupNames()!=null && !condition.getGroupNames().isEmpty()){
                //字段遍历查询   可能不能模糊查询
                query.addCriteria(Criteria.where("groupName").in(condition.getGroupNames()));
            }
            query.addCriteria(Criteria.where("isCorrect").is(condition.getIsCorrect()));
        }else {
            throw new EmpException(ErrCodeConstant.ILLEGAL_PARAM, "考勤字段不能为空！", condition);
        }
        List<AliWorkDTO> attendencesByCondition = mongoTemplate.find(query, AliWorkDTO.class, collectionName);
        return attendencesByCondition;
    }

    public List<AliWorkDTO> findAll() {
//        return mongoTemplate.findAll(AliWorkDTO.class);
//        Query query = new Query();
//        query.with(new Sort(new Sort.Order(Sort.Direction.DESC,"aliNumber")));
        return mongoTemplate.findAll(AliWorkDTO.class);
    }

    /**
     * 根据调休选择出来还有调休单的
     *
     * @return approvalList 返回调休单中的请假数据   List<AliWorkDTO>
     */
    public List<AliWorkDTO> findApprovalList() {
        //2.2 将调休单中的请假的数据读取出来。（不要调休或者是外出）
        Query query = new Query();
        query.addCriteria(Criteria.where("dateStr").regex(".*?\\" + DateUtils.create_yy_mm() + ".*"));
        query.addCriteria(Criteria.where("approval").ne(null).ne(""));
        List<AliWorkDTO> approvalList = mongoTemplate.find(query, AliWorkDTO.class);
        return approvalList;
    }

    public List<AliWorkDTO> findListContainsApproval(@NonNull String collectionName) throws CommonException {
        List<AliWorkDTO> approvalList = null;
        Query query = new Query();
        query.addCriteria(Criteria.where("approval").ne(null));
        try {
            approvalList = mongoTemplate.find(query, AliWorkDTO.class, collectionName);
        } catch (Exception e) {
            log.error("================根据mongodb名称查询数据失败", e);
            return null;
        }
        return approvalList;
    }

    public void saveAttendaceMessage(List<AttendenceMessage> attendenceMessageList) {
        for (AttendenceMessage attendenceMessage : attendenceMessageList) {
            Query query = new Query();
            query.addCriteria(Criteria.where("messageType").is(attendenceMessage.getMessageType()));
            Update update = Update.update("content", attendenceMessage.getContent());
            mongoTemplate.upsert(query, update, AttendenceMessage.class);
        }
    }

    public List<AttendenceMessage> findAttendaceMessage() {
        return mongoTemplate.findAll(AttendenceMessage.class);
    }

    public Integer dropCollection(String collectionName){
        int resCount = 0;
        try{
            mongoTemplate.dropCollection(collectionName);
        }catch(Exception e){
            log.error(e);
            resCount = ErrCodeConstant.DB_ERR;
        }
        return resCount;
    }

    public void updateCorrect(List<AbnormalAttendanceDTO> abnormalAttendanceDTOS){
        Query query = new Query();
        for (AbnormalAttendanceDTO abnormalAttendanceDTO : abnormalAttendanceDTOS){
            query.addCriteria(Criteria.where(abnormalAttendanceDTO.getDateStr()).is(abnormalAttendanceDTO.getDateStr()));
            if (null != abnormalAttendanceDTO && null != abnormalAttendanceDTO.getAliNumber()){
                query.addCriteria(Criteria.where("aliNumber").is(abnormalAttendanceDTO.getAliNumber()));
            }else {
                query.addCriteria(Criteria.where("employeeName").is(abnormalAttendanceDTO.getEmployeeName()));
            }
            Update update = Update.update("isCorrect", abnormalAttendanceDTO.getIsCorrect());
            mongoTemplate.upsert(query, update, MongoCollectionConstant.ABNORMAL_ATTENDENCE);
        }

    }




    /**
     * 快速查询  现在快速查询提供的方式是：姓名和钉钉群名称
     * @param fastInquiry  快速查询字段
     * @return
     */
    public List<AbnormalAttendanceDTO> getFastInquiryList(String fastInquiry) throws EmpException {
        Query query = new Query();
        Criteria criteria = new Criteria();
        if (StringUtils.isEmpty(fastInquiry)){
            throw new EmpException(ErrCodeConstant.ILLEGAL_PARAM, "快速查询参数不能为空！");
        }
        criteria.orOperator(Criteria.where("employeeName").regex(fastInquiry),
                Criteria.where("groupName").regex(fastInquiry));
        List<AbnormalAttendanceDTO> abnormalAttendanceDTOS = mongoTemplate.find(query.addCriteria(criteria), AbnormalAttendanceDTO.class);
        return abnormalAttendanceDTOS;
    }



}
